package com.irdstudio.efp.esb.api.rest.yed.loanManage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.ESBConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.efp.console.service.facade.PrdInfoService;
import com.irdstudio.efp.console.service.vo.PrdInfoVO;
import com.irdstudio.efp.ctr.service.facade.CtrLoanContService;
import com.irdstudio.efp.ctr.service.vo.CtrLoanContVO;
import com.irdstudio.efp.edoc.service.bo.UpLoadFileVO;
import com.irdstudio.efp.edoc.service.facade.UpLoadFileService;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.GroupeInterface;
import com.irdstudio.efp.esb.api.rest.EsbController;
import com.irdstudio.efp.esb.api.rest.yed.req.ReqCtrLoanQueryBean;
import com.irdstudio.efp.esb.api.rest.yed.resp.CtrLoanArry;
import com.irdstudio.efp.esb.api.rest.yed.resp.RespCtrLoanQueryBean;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.loan.service.facade.AccLoanService;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 合同列表查询接口 渠道端 -》网贷
 *
 * @author liangcongming :2020/8/4 16:32
 * @version 0.1
 * @date 2020/8/4 16:32
 * @since 2020/8/4 16:32
 */
@RestController
@RequestMapping("/esb")
public class YedCtrLoanQueryController implements EsbController {

    private static Logger logger = LoggerFactory.getLogger(YedCtrLoanQueryController.class);

    @Autowired
    @Qualifier("upLoadFileService")
    private UpLoadFileService upLoadFileService;

    @Autowired
    @Qualifier("ctrLoanContService")
    private CtrLoanContService ctrLoanContService;// 合同信息

    @Autowired
    @Qualifier("prdInfoService")
    private PrdInfoService prdInfoService;

    @Autowired
    @Qualifier("accLoanService")
    private AccLoanService accLoanService;

    /**
     * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("esbReqServiceBean")
    public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
        logger.info("校验 ESB请求系统头和请求应用头对象!");
        EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
        return esbReqServiceBean;
    }

    /**
     * 获取ESB请求对象，校验 ESB请求体对象
     *
     * @param request 请求对象集合
     * @return
     */
    @ModelAttribute("ctrLoanQueryBean")
    public ReqCtrLoanQueryBean getReqEsbBodyBean(HttpServletRequest request) {
        logger.info("校验 ESB请求体对象！");
        String esbReqBody = (String) request.getAttribute("esbReqBody");
        return JSONObject.parseObject(esbReqBody, ReqCtrLoanQueryBean.class);
    }

    @PostMapping("/SERVICE_30230006_04")
    public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
                                     @Validated({GroupeInterface.yed.class}) @ModelAttribute("ctrLoanQueryBean") ReqCtrLoanQueryBean reqCtrLoanQueryBean, BindingResult br2, Exception exception){
        String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
        logger.info("优e贷合同列表查询开始,全局流水号为：[{}]", glblSrlNo);
        List<CtrLoanArry> ctrLoanArryList = new ArrayList<CtrLoanArry>();
        try {
            // 参数校验
            validateBean(esbReqServiceBean, br1, reqCtrLoanQueryBean, br2, exception, logger);
            // 设置系统头对象
            setSysHeadFieldThreadLocal(esbReqServiceBean);

            if (Objects.nonNull(exception)) {
                throw exception;
            }

            //1.判断产品
            PrdInfoVO prdParam = new PrdInfoVO();
            prdParam.setPrdId(reqCtrLoanQueryBean.getPrdId());
            PrdInfoVO prdInfoVO = prdInfoService.queryByPk(prdParam);

            if (Objects.isNull(prdInfoVO)) {
                throw new BizException(EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(), "产品ID错误，请检查！");
            }

            /** 单个合同查询**/
            // 如果借据号不为空，则进行单个合同查询（esb文档治理的授信协议号字段，实际送的是借据号）
            if(StringUtil.isNotEmpty(reqCtrLoanQueryBean.getCrAgrmtNo())){

                // 【第一步】根据借据号查找用信号
                AccLoanVO accLoanVO = new AccLoanVO();
                accLoanVO.setBillNo(reqCtrLoanQueryBean.getCrAgrmtNo());
                AccLoanVO quyAccLoanVO = accLoanService.queryByPk(accLoanVO);
                if (Objects.isNull(quyAccLoanVO)) {
                    throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(), "根据借据号未能找到借据信息！");
                }

                //【第二步】根据用信号查找影像信息
                UpLoadFileVO upLoadFileVO = new UpLoadFileVO();
                upLoadFileVO.setImageType("Y02");//优e贷借款合同 影像类型
                upLoadFileVO.setApplySeq(quyAccLoanVO.getApplySeq());
                UpLoadFileVO qryupLoadFileVO = upLoadFileService.queryUploadFileByApplySeqAndImageType(upLoadFileVO);
                if(!validateUpLoadFileVO(qryupLoadFileVO,reqCtrLoanQueryBean)){
                    throw new BizException(EsbRetCodeStandard.WFJKYWGZ.getValue(),"影像信息校验不成功！");
                }

                // 【第三步】根据用信号查询合同信息
                CtrLoanContVO ctrLoanContVO = new CtrLoanContVO();
                ctrLoanContVO.setContNo(quyAccLoanVO.getApplySeq());
                CtrLoanContVO queryCtrLoanContVO = ctrLoanContService.queryByPk(ctrLoanContVO);
                if (Objects.isNull(queryCtrLoanContVO)) {
                    throw new BizException("根据影像平台合同号未查到合同信息，用信号为：" + quyAccLoanVO.getApplySeq());
                }

                //【第四步】组装响应体
                CtrLoanArry ctrLoanArry = new CtrLoanArry();
                ctrLoanArry.setSigndate(queryCtrLoanContVO.getSignDate());
                ctrLoanArry.setContno(queryCtrLoanContVO.getContNo());
                ctrLoanArry.setBatch(qryupLoadFileVO.getBatch());
                ctrLoanArry.setCreatetime(qryupLoadFileVO.getCreateTime());
                ctrLoanArry.setCncontno(StringUtils.isBlank(queryCtrLoanContVO.getCnContNo()) ? "" : queryCtrLoanContVO.getCnContNo());
                ctrLoanArryList.add(ctrLoanArry);

                return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                        JSON.toJSONString(buildRespCtrLoanQueryBean(ESBConstant.SUCCESS, "查询成功", ctrLoanArryList)), //
                        EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), //
                        EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), //
                        "查询成功");
            }else {
                /** 合同列表查询**/
                // 【第一步】根据身份证等查询影像信息
                UpLoadFileVO upLoadFileVO = new UpLoadFileVO();
                upLoadFileVO.setCertCode(reqCtrLoanQueryBean.getCertcode());
                upLoadFileVO.setCusName(reqCtrLoanQueryBean.getCusname());
                upLoadFileVO.setPrdName(reqCtrLoanQueryBean.getPrdname());
                upLoadFileVO.setImageType("Y02");//优e贷借款合同 影像类型
                upLoadFileVO.setState("SUCCESS");
                List<UpLoadFileVO> queryUpLoadFileVOList = upLoadFileService.queryUploadFile(upLoadFileVO);

                if (Objects.isNull(queryUpLoadFileVOList)) {
                    throw new Exception("数据查询出现异常!");
                }

                if (queryUpLoadFileVOList.isEmpty()) {
                    throw new BizException("根据身份证、产品名称、客户姓名未查到成功上传影像合同信息！");
                }

                for (UpLoadFileVO vo : queryUpLoadFileVOList) {
                    // 【第二步】根据用信号查询合同信息
                    CtrLoanContVO ctrLoanContVO = new CtrLoanContVO();
                    ctrLoanContVO.setContNo(vo.getApplySeq());
                    CtrLoanContVO queryCtrLoanContVO = ctrLoanContService.queryByPk(ctrLoanContVO);
                    if (Objects.isNull(queryCtrLoanContVO)) {
                        logger.info("根据影像平台合同号未查到合同信息，用信号为：" + vo.getApplySeq());
                        continue;
                    }
                    //【第三步】组装响应体
                    CtrLoanArry ctrLoanArry = new CtrLoanArry();
                    ctrLoanArry.setSigndate(queryCtrLoanContVO.getSignDate());
                    ctrLoanArry.setContno(queryCtrLoanContVO.getContNo());
                    ctrLoanArry.setBatch(vo.getBatch());
                    ctrLoanArry.setCreatetime(vo.getCreateTime());
                    ctrLoanArry.setCncontno(StringUtils.isBlank(queryCtrLoanContVO.getCnContNo()) ? "" : queryCtrLoanContVO.getCnContNo());
                    ctrLoanArryList.add(ctrLoanArry);
                }

                return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                        JSON.toJSONString(buildRespCtrLoanQueryBean(ESBConstant.SUCCESS, "查询成功", ctrLoanArryList)), //
                        EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), //
                        EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), //
                        "查询成功");
            }
        } catch (BizException ex) {
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespCtrLoanQueryBean(EsbBizEnums.RetCodeEnum.SJCLYC.getVALUE(), ex.getMessage(), ctrLoanArryList)), //
                    EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), //
                    EsbBizEnums.RetCodeEnum.SJCLYC.getVALUE(), //
                    ex.getMessage());

        } catch (Exception e) {
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespCtrLoanQueryBean(EsbBizEnums.RetCodeEnum.JKYDCSJYBTG.getVALUE(), e.getMessage(), ctrLoanArryList)), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.JKYDCSJYBTG.getVALUE(), //
                    e.getMessage());
        } finally {
            logger.info("优e贷合同列表查询结束,全局流水号为：[{}]", glblSrlNo);
        }
    }


    private RespCtrLoanQueryBean buildRespCtrLoanQueryBean(String retCode, String retMsg, List<CtrLoanArry> ctrLoanArries) {
        RespCtrLoanQueryBean bean = new RespCtrLoanQueryBean();
        bean.setRetCode(retCode);
        bean.setRetMsg(retMsg);
        bean.setCtrLoanArryList(ctrLoanArries);
        return bean;
    }

    /**
     * 校验影像信息数据是否正确
     * @param queryUpLoadFileVO
     * @param queryNlsApplyInfoVO
     * @return
     */
    private boolean validateUpLoadFileVO(UpLoadFileVO queryUpLoadFileVO,ReqCtrLoanQueryBean reqCtrLoanQueryBean){
        Objects.requireNonNull(queryUpLoadFileVO);
        Boolean flag = true;
        if(!"SUCCESS".equals(queryUpLoadFileVO.getState())){
            logger.error("影像状态不为成功");
            return false;
        }
        if(Objects.isNull(queryUpLoadFileVO.getBatch())){
            logger.error("影像批次号为空");
            return false;
        }
        if(!reqCtrLoanQueryBean.getCertcode().equals(queryUpLoadFileVO.getCertCode())){
            logger.error("身份证号码不匹配");
            return false;
        }
        if(!reqCtrLoanQueryBean.getCusname().equals(queryUpLoadFileVO.getCusName())){
            logger.error("客户姓名不匹配");
            return false;
        }
        return flag;
    }
}